home *** CD-ROM | disk | FTP | other *** search
- Path: anvil.ugrad.cs.ubc.ca!not-for-mail
- From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
- Newsgroups: comp.lang.c
- Subject: Re: need for function prototypes
- Date: 29 Feb 1996 13:42:22 -0800
- Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
- Message-ID: <4h56juINNmd0@anvil.ugrad.cs.ubc.ca>
- References: <31333401.7D03@stat.uni-muenchen.de>
- NNTP-Posting-Host: anvil.ugrad.cs.ubc.ca
-
- In article <31333401.7D03@stat.uni-muenchen.de>,
- watzka <watzka@stat.uni-muenchen.de> wrote:
- >Chris Rossall wrote:
- >>
- >> Hello I am having trouble understanding why I should use function
- >> prototypes. I mean,if the function is defined before it is used,the
- >> compiler should have enough information about the parameters to
- >> produce correct code anyway.
- >
- >Yes, indeed, a function definition provides enough information to
- >produce correct code. If your function returns an int and has no
- >variable argument list, correct code can be produced without a
- >function prototype.
-
- The function definition serves as a prototype, when you are ``down wind'' in
- the scope---that is, if the function you are calling is defined before the
- place where you are calling it. This is not a case of not having a prototype.
- Within a single translation unit, a prototype serves analogously to a Pascal
- ``forward reference'', which is one answer that we can give to Chris Rossall:
-
- If you have two mutually recursive functions, you can't avoid using a
- prototype (unless you correctly take advantage of the argument promotion rules
- that are in effect when calling unprototyped functions):
-
- float a(float x) { /* calls b() */ }
-
- float b(float x) { /* calls a() */ }
-
- Here, a *requires* a prototype of b, from which it can infer the return value
- and the parameter type. Even if you rewrote them in old-style C, you would
- still need a prior declaration to get the return type right.
-
- >Function prototypes are useful for _checking_ code, esp. in situations
- >where the first call to a function in a translation unit will precede
- >the definition of that function.
-
- Correct code is produced, but not necessarily a correct calling sequence if no
- definition or correct prototype declaration for the called function is found
- prior to the inocation. If a call (any call, not just the first) precedes the
- definition of the function, an incorrect calling sequence will be generated,
- and undefined behavior will result. In the above example, when a invokes b, a
- default prototype is implicitly generated which is ``int b()''. The call to
- b() cannot be correct because b() returns a float, not an int. Furthermore,
- since b() is not prototyped, if a() passes a float argument to b(), it will be
- promoted to a double in the calling sequence. However, b() is a new-style
- function which means that the types of arguments and parameters have to match
- exactly; i.e. it expects a float.
- --
-
-